/** * DataTypes - Supported Java Data Types and static utility methods * * Copyright (c) 2002 * Marty Phelan, All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ package com.taursys.util; import java.util.Hashtable; import java.sql.Types; import java.math.BigDecimal; import java.text.DateFormat; import java.text.ParseException; /** * This class provides definition, conversion, and simple parsing for known data types. */ public class DataTypes { public static final int TYPE_UNDEFINED = -1; public static final int TYPE_STRING = 0; public static final int TYPE_BIGDECIMAL = 1; public static final int TYPE_TIMESTAMP = 2; public static final int TYPE_BOOLEAN = 3; public static final int TYPE_INT = 4; public static final int TYPE_BYTE = 5; public static final int TYPE_SHORT = 6; public static final int TYPE_LONG = 7; public static final int TYPE_FLOAT = 8; public static final int TYPE_DATE = 9; public static final int TYPE_TIME = 10; public static final int TYPE_DOUBLE = 11; public static final int TYPE_SQL_DATE = 12; private static DateFormat df = DateFormat.getDateTimeInstance( DateFormat.LONG, DateFormat.LONG); /** * Get the default DataFormat used by the parse/format routines. * By default it is initialized to DateFormat.getDateTimeInstance( * DateFormat.LONG, DateFormat.LONG). * @return the default DataFormat used by the parse/format routines */ public static DateFormat getDefaultDateFormat() { return df; } /** * Set the default DataFormat used by the parse/format routines. * By default it is initialized to DateFormat.getDateTimeInstance( * DateFormat.LONG, DateFormat.LONG). * @param dfNew the default DataFormat used by the parse/format routines */ public static void setDefaultDateFormat(DateFormat dfNew) { if (dfNew == null) throw new IllegalArgumentException("Default Date Format cannot be set to null"); df = dfNew; } private static Hashtable javaTypeNames = new Hashtable(); private static final Class[] CLASSES_FOR_TYPES = { String.class, BigDecimal.class, java.sql.Timestamp.class, Boolean.class, Integer.class, Byte.class, Short.class, Long.class, Float.class, java.util.Date.class, java.sql.Time.class, Double.class, java.sql.Date.class, }; private static final String[] JAVA_NAMES_FOR_TYPES = { "java.lang.String", "java.math.BigDecimal", "java.sql.Timestamp", "java.lang.Boolean", "java.lang.Integer", "java.lang.Byte", "java.lang.Short", "java.lang.Long", "java.lang.Float", "java.util.Date", "java.sql.Time", "java.lang.Double", "java.sql.Date", }; static { javaTypeNames.put("java.lang.String", new Integer(TYPE_STRING)); javaTypeNames.put("java.math.BigDecimal", new Integer(TYPE_BIGDECIMAL)); javaTypeNames.put("java.sql.Timestamp", new Integer(TYPE_TIMESTAMP)); javaTypeNames.put("java.lang.Boolean", new Integer(TYPE_BOOLEAN)); javaTypeNames.put("java.lang.Integer", new Integer(TYPE_INT)); javaTypeNames.put("java.lang.Byte", new Integer(TYPE_BYTE)); javaTypeNames.put("java.lang.Short", new Integer(TYPE_SHORT)); javaTypeNames.put("java.lang.Long", new Integer(TYPE_LONG)); javaTypeNames.put("java.lang.Float", new Integer(TYPE_FLOAT)); javaTypeNames.put("java.util.Date", new Integer(TYPE_DATE)); javaTypeNames.put("java.sql.Time", new Integer(TYPE_TIME)); javaTypeNames.put("java.lang.Double", new Integer(TYPE_DOUBLE)); javaTypeNames.put("java.sql.Date", new Integer(TYPE_SQL_DATE)); // Special names for primatives javaTypeNames.put("int", new Integer(TYPE_INT)); javaTypeNames.put("boolean", new Integer(TYPE_BOOLEAN)); javaTypeNames.put("char", new Integer(TYPE_STRING)); javaTypeNames.put("byte", new Integer(TYPE_BYTE)); javaTypeNames.put("short", new Integer(TYPE_SHORT)); javaTypeNames.put("long", new Integer(TYPE_LONG)); javaTypeNames.put("float", new Integer(TYPE_FLOAT)); javaTypeNames.put("double", new Integer(TYPE_DOUBLE)); } /** * Private constructor - this class is not intended to be instantiated */ private DataTypes() { } /** * Returns the class name for the given Java data type. * @param javaDataType constant (see DataTypes.TYPE_XXX) * @return Class name for the given Java data type * @throws UnsupportedDataTypeException if the given value is not a known type. */ public static String getJavaNameForType(int javaDatType) throws UnsupportedDataTypeException { checkJavaDataType(javaDatType); return JAVA_NAMES_FOR_TYPES[javaDatType]; } /** * Returns the Class for the given Java data type. * @param javaDataType constant (see DataTypes.TYPE_XXX) * @return Class for the given Java data type * @throws UnsupportedDataTypeException if the given value is not a known type. */ public static Class getClassForType(int javaDatType) throws UnsupportedDataTypeException { checkJavaDataType(javaDatType); return CLASSES_FOR_TYPES[javaDatType]; } /** * Checks given index to ensure it is valid type otherwise throws UnsupportedDataTypeException. */ public static void checkJavaDataType(int i) throws UnsupportedDataTypeException { if (i < 0 || i >= JAVA_NAMES_FOR_TYPES.length) throw new UnsupportedDataTypeException(); } /** * Returns an int id for the given data type or TYPE_UNDEFINED if unknown. * @return an int id for the given data type or TYPE_UNDEFINED if unknown */ public static int getDataType(String className) { Integer integer = (Integer)javaTypeNames.get(className); if (integer != null) return integer.intValue(); else return TYPE_UNDEFINED; } /** * Returns an object of the type indicated by javaDataType set from the * value of the given object. This effectively converts the given * object to another type of object. There must be a reasonable * expectation of conversion, otherwise an Exception * ("Unsupported Data Type Conversion") will be thrown. * A change of types can also cause rounding or truncation. */ private static Object convert(int javaDataType, Number value) throws UnsupportedConversionException, UnsupportedDataTypeException { checkJavaDataType(javaDataType); switch (javaDataType) { case TYPE_BIGDECIMAL: return new BigDecimal(((Number)value).toString()); case TYPE_BYTE: return new Byte(((Number)value).byteValue()); case TYPE_DOUBLE: return new Double(((Number)value).doubleValue()); case TYPE_FLOAT: return new Float(((Number)value).floatValue()); case TYPE_INT: return new Integer(((Number)value).intValue()); case TYPE_LONG: return new Long(((Number)value).longValue()); case TYPE_SHORT: return new Short(((Number)value).shortValue()); default: throw new UnsupportedConversionException(); } } /** * Returns an object of the type indicated by javaDataType set from the * value of the given object. This effectively converts the given * object to another type of object. There must be a reasonable * expectation of conversion, otherwise an Exception * ("Unsupported Data Type Conversion") will be thrown. * A change of types can also cause rounding or truncation. */ private static Object convert(int javaDataType, java.util.Date value) throws UnsupportedConversionException { checkJavaDataType(javaDataType); switch (javaDataType) { case TYPE_DATE: return value; case TYPE_TIME: return new java.sql.Time(((java.util.Date)value).getTime()); case TYPE_TIMESTAMP: return new java.sql.Timestamp(((java.util.Date)value).getTime()); case TYPE_SQL_DATE: return new java.sql.Date(((java.util.Date)value).getTime()); default: throw new UnsupportedConversionException(); } } /** * Returns an object of the type indicated by javaDataType set from the * value of the given object. This effectively converts the given * object to another type of object. There must be a reasonable * expectation of conversion, otherwise an Exception * ("Unsupported Data Type Conversion") will be thrown. * A change of types can also cause rounding or truncation. */ private static Object convert(int javaDataType, String value) throws UnsupportedConversionException, UnsupportedDataTypeException { checkJavaDataType(javaDataType); if (javaDataType == TYPE_STRING) return value; else throw new UnsupportedConversionException(); } /** * Returns an object of the type indicated by javaDataType set from the * value of the given object. This effectively converts the given * object to another type of object. There must be a reasonable * expectation of conversion, otherwise an Exception * ("Unsupported Data Type Conversion") will be thrown. * A change of types can also cause rounding or truncation. */ public static Object convert(int javaDataType, Object value) throws UnsupportedConversionException, UnsupportedDataTypeException { if (value instanceof String) return convert(javaDataType, (String)value); else if (value instanceof java.util.Date) return convert(javaDataType, (java.util.Date)value); else if (value instanceof Number) return convert(javaDataType, (Number)value); else throw new UnsupportedConversionException(); } /** * Returns a new object of type indicated by javaDataType with parsed given value. * @param javaDataType indicates data type of value (see TYPE_xxx constants). * @param String value to parse. * @return Object representing parsed value of given String. * @throws UnsupportedDataTypeException if unknown javaDataType given. * @throws ParseException if given value cannot be parsed. */ public static Object parse(int javaDataType, String value) throws ParseException, UnsupportedDataTypeException { switch (javaDataType) { case TYPE_STRING: return value; case TYPE_BOOLEAN: return new Boolean(value); case TYPE_DATE: return df.parse(value); case TYPE_SQL_DATE: return new java.sql.Date(df.parse(value).getTime()); case TYPE_TIME: return new java.sql.Time(df.parse(value).getTime()); case TYPE_TIMESTAMP: return new java.sql.Timestamp(df.parse(value).getTime()); case TYPE_BIGDECIMAL: return new BigDecimal(value); case TYPE_BYTE: return new Byte(value); case TYPE_DOUBLE: return new Double(value); case TYPE_FLOAT: return new Float(value); case TYPE_INT: return new Integer(value); case TYPE_LONG: return new Long(value); case TYPE_SHORT: return new Short(value); default: throw new UnsupportedDataTypeException(); } } /** * Returns a default formatted String for the given object. * If the type is <code>TYPE_UNDEFINED</code>, the <code>toString()</code> * method is used. * @param javaDataType indicates data type of value (see TYPE_xxx constants). * @param value is the object to format as a String * @return formatted String using default format for Object type. * @throws UnsupportedDataTypeException if unknown javaDataType given. */ public static String format(int javaDataType, Object value) throws UnsupportedDataTypeException { switch (javaDataType) { case TYPE_STRING: return value.toString(); case TYPE_BOOLEAN: return value.toString(); case TYPE_DATE: return df.format(value); case TYPE_SQL_DATE: return df.format(value); case TYPE_TIME: return df.format(value); case TYPE_TIMESTAMP: return df.format(value); case TYPE_BIGDECIMAL: return value.toString(); case TYPE_BYTE: return value.toString(); case TYPE_DOUBLE: return value.toString(); case TYPE_FLOAT: return value.toString(); case TYPE_INT: return value.toString(); case TYPE_LONG: return value.toString(); case TYPE_SHORT: return value.toString(); case TYPE_UNDEFINED: return value.toString(); default: throw new UnsupportedDataTypeException(); } } }